package loaders

import (
	"context"
	"io/ioutil"
	"path/filepath"
	"strings"
	"time"

	"github.com/PuerkitoBio/goquery"
)

// HTMLLoader HTML文件加载器
type HTMLLoader struct {
	*BaseLoader
	StripTags []string // 需要移除的标签
	KeepTags  []string // 需要保留的标签
}

// NewHTMLLoader 创建HTML文件加载器
func NewHTMLLoader(filePath string) *HTMLLoader {
	return &HTMLLoader{
		BaseLoader: NewBaseLoader(filePath),
		StripTags:  []string{"script", "style", "iframe", "noscript", "footer", "nav", "aside"},
		KeepTags:   []string{"p", "h1", "h2", "h3", "h4", "h5", "h6", "div", "span", "article", "main"},
	}
}

// Load 加载HTML文件
func (l *HTMLLoader) Load(ctx context.Context) ([]Document, error) {
	startTime := time.Now()
	l.logInfo("开始加载HTML文件")

	// 读取文件内容
	content, err := ioutil.ReadFile(l.FilePath)
	if err != nil {
		l.logError(err, "读取HTML文件失败")
		return nil, err
	}

	// 解析HTML
	doc, err := goquery.NewDocumentFromReader(strings.NewReader(string(content)))
	if err != nil {
		l.logError(err, "解析HTML文件失败")
		return nil, err
	}

	// 移除不需要的标签
	for _, tag := range l.StripTags {
		doc.Find(tag).Remove()
	}

	// 提取文本内容
	var extractedText strings.Builder

	// 保留的标签中的文本
	for _, tag := range l.KeepTags {
		doc.Find(tag).Each(func(i int, s *goquery.Selection) {
			text := strings.TrimSpace(s.Text())
			if text != "" {
				extractedText.WriteString(text)
				extractedText.WriteString("\n\n")
			}
		})
	}

	// 如果没有找到保留的标签内容，则提取body文本
	if extractedText.Len() == 0 {
		bodyText := strings.TrimSpace(doc.Find("body").Text())
		extractedText.WriteString(bodyText)
	}

	// 清理文本
	cleanText := extractedText.String()
	cleanText = strings.TrimSpace(cleanText)
	cleanText = strings.ReplaceAll(cleanText, "\r\n", "\n")

	// 合并多余的空行
	for strings.Contains(cleanText, "\n\n\n") {
		cleanText = strings.ReplaceAll(cleanText, "\n\n\n", "\n\n")
	}

	// 提取标题
	title := doc.Find("title").Text()

	// 创建文档对象
	docObj := Document{
		Content: cleanText,
		MetaData: map[string]interface{}{
			"file_path":    l.FilePath,
			"file_name":    filepath.Base(l.FilePath),
			"file_ext":     "html",
			"content_type": "text/html",
			"loader_type":  "HTMLLoader",
			"load_time":    startTime.Format(time.RFC3339),
			"content_size": len(cleanText),
			"title":        title,
		},
		FilePath: l.FilePath,
	}

	// 提取元数据
	if description := doc.Find("meta[name='description']").AttrOr("content", ""); description != "" {
		docObj.MetaData["description"] = description
	}

	if keywords := doc.Find("meta[name='keywords']").AttrOr("content", ""); keywords != "" {
		docObj.MetaData["keywords"] = keywords
	}

	l.logInfo("HTML文件加载成功", map[string]interface{}{
		"content_size": len(cleanText),
		"load_time_ms": time.Since(startTime).Milliseconds(),
	})

	return []Document{docObj}, nil
}
